package pl.edu.pw.perg.compinfodb.manager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import pl.edu.pw.perg.compinfodb.dao.IConnectorNameDAO;
import pl.edu.pw.perg.compinfodb.entities.ConnectorName;
import pl.edu.pw.perg.compinfodb.entities.ElementType;

public class ConnectorNameManager extends GenericManager<ConnectorName> implements IConnectorNameManager {

	private Map<ElementType, Map<Integer, ConnectorName>> inputMap = new HashMap<ElementType, Map<Integer, ConnectorName>>();
	private Map<ElementType, Map<Integer, ConnectorName>> outputMap = new HashMap<ElementType, Map<Integer, ConnectorName>>();
	
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public Map<Integer, ConnectorName> getInputNamesForType(ElementType type) {
		return getInputNamesCached(type);
	}
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public Map<Integer, ConnectorName> getOutputNamesForType(ElementType type) {
		return getOutputNamesCached(type);
	}
	
	private Map<Integer, ConnectorName> getNamesCached(ElementType type, boolean inputFlag){
		Map<Integer, ConnectorName> map = null;
		Map<ElementType, Map<Integer, ConnectorName>> cache = inputFlag ? inputMap : outputMap;
		if((map = cache.get(type)) != null)
			return map;
		
		List<ConnectorName> connectorNames = findConnectorNames(type, inputFlag); 
		map = new HashMap<Integer, ConnectorName>();
		for (int i = 0; i < connectorNames.size(); i++) {
			ConnectorName cn = connectorNames.get(i);
			if(cn != null)
				map.put(cn.getConnectorIndex(), cn);
		}
		cache.put(type, map);
		return map; 
		
	}
	
	private Map<Integer, ConnectorName> getInputNamesCached(ElementType type){
		return getNamesCached(type, true);
	}
	
	private Map<Integer, ConnectorName> getOutputNamesCached(ElementType type){
		return getNamesCached(type, false);
	}
	
//	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public List<ConnectorName> findConnectorNames(ElementType type, boolean inputFlag){
		ConnectorName cn = new ConnectorName();
		cn.setType(type);
		cn.setIo(inputFlag);
//		TODO: naprawic!
//		return getGenericDAO().findByExample(cn, new String[]{"id", "name", "connectorIndex"});
		return ((IConnectorNameDAO) getGenericDAO()).findConnectorNamesByTypeAndFlag(type, inputFlag);

	}
}
